1 /* 2 * Copyright (C) 2007 The Guava Authors 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package com.google.common.collect; 18 19 import static com.google.common.base.Preconditions.checkNotNull; 20 21 import com.google.common.annotations.GwtCompatible; 22 23 import java.util.Collection; 24 import java.util.Comparator; 25 import java.util.SortedSet; 26 import java.util.TreeMap; 27 import java.util.TreeSet; 28 29 import javax.annotation.Nullable; 30 31 /** 32 * Implementation of {@code Multimap} whose keys and values are ordered by 33 * their natural ordering or by supplied comparators. In all cases, this 34 * implementation uses {@link Comparable#compareTo} or {@link 35 * Comparator#compare} instead of {@link Object#equals} to determine 36 * equivalence of instances. 37 * 38 * <p><b>Warning:</b> The comparators or comparables used must be <i>consistent 39 * with equals</i> as explained by the {@link Comparable} class specification. 40 * Otherwise, the resulting multiset will violate the general contract of {@link 41 * SetMultimap}, which it is specified in terms of {@link Object#equals}. 42 * 43 * <p>The collections returned by {@code keySet} and {@code asMap} iterate 44 * through the keys according to the key comparator ordering or the natural 45 * ordering of the keys. Similarly, {@code get}, {@code removeAll}, and {@code 46 * replaceValues} return collections that iterate through the values according 47 * to the value comparator ordering or the natural ordering of the values. The 48 * collections generated by {@code entries}, {@code keys}, and {@code values} 49 * iterate across the keys according to the above key ordering, and for each 50 * key they iterate across the values according to the value ordering. 51 * 52 * <p>The multimap does not store duplicate key-value pairs. Adding a new 53 * key-value pair equal to an existing key-value pair has no effect. 54 * 55 * <p>Null keys and values are permitted (provided, of course, that the 56 * respective comparators support them). All optional multimap methods are 57 * supported, and all returned views are modifiable. 58 * 59 * <p>This class is not threadsafe when any concurrent operations update the 60 * multimap. Concurrent read operations will work correctly. To allow concurrent 61 * update operations, wrap your multimap with a call to {@link 62 * Multimaps#synchronizedSortedSetMultimap}. 63 * 64 * <p>See the Guava User Guide article on <a href= 65 * "http://code.google.com/p/guava-libraries/wiki/NewCollectionTypesExplained#Multimap"> 66 * {@code Multimap}</a>. 67 * 68 * @author Jared Levy 69 * @author Louis Wasserman 70 * @since 2.0 (imported from Google Collections Library) 71 */ 72 @GwtCompatible(serializable = true, emulated = true) 73 public class TreeMultimap<K, V> extends AbstractSortedKeySortedSetMultimap<K, V> { 74 private transient Comparator<? super K> keyComparator; 75 private transient Comparator<? super V> valueComparator; 76 77 /** 78 * Creates an empty {@code TreeMultimap} ordered by the natural ordering of 79 * its keys and values. 80 */ 81 public static <K extends Comparable, V extends Comparable> 82 TreeMultimap<K, V> create() { 83 return new TreeMultimap<K, V>(Ordering.natural(), Ordering.natural()); 84 } 85 86 /** 87 * Creates an empty {@code TreeMultimap} instance using explicit comparators. 88 * Neither comparator may be null; use {@link Ordering#natural()} to specify 89 * natural order. 90 * 91 * @param keyComparator the comparator that determines the key ordering 92 * @param valueComparator the comparator that determines the value ordering 93 */ 94 public static <K, V> TreeMultimap<K, V> create( 95 Comparator<? super K> keyComparator, 96 Comparator<? super V> valueComparator) { 97 return new TreeMultimap<K, V>(checkNotNull(keyComparator), 98 checkNotNull(valueComparator)); 99 } 100 101 /** 102 * Constructs a {@code TreeMultimap}, ordered by the natural ordering of its 103 * keys and values, with the same mappings as the specified multimap. 104 * 105 * @param multimap the multimap whose contents are copied to this multimap 106 */ 107 public static <K extends Comparable, V extends Comparable> 108 TreeMultimap<K, V> create(Multimap<? extends K, ? extends V> multimap) { 109 return new TreeMultimap<K, V>(Ordering.natural(), Ordering.natural(), 110 multimap); 111 } 112 113 TreeMultimap(Comparator<? super K> keyComparator, 114 Comparator<? super V> valueComparator) { 115 super(new TreeMap<K, Collection<V>>(keyComparator)); 116 this.keyComparator = keyComparator; 117 this.valueComparator = valueComparator; 118 } 119 120 private TreeMultimap(Comparator<? super K> keyComparator, 121 Comparator<? super V> valueComparator, 122 Multimap<? extends K, ? extends V> multimap) { 123 this(keyComparator, valueComparator); 124 putAll(multimap); 125 } 126 127 /** 128 * {@inheritDoc} 129 * 130 * <p>Creates an empty {@code TreeSet} for a collection of values for one key. 131 * 132 * @return a new {@code TreeSet} containing a collection of values for one 133 * key 134 */ 135 @Override SortedSet<V> createCollection() { 136 return new TreeSet<V>(valueComparator); 137 } 138 139 @Override 140 Collection<V> createCollection(@Nullable K key) { 141 if (key == null) { 142 keyComparator().compare(key, key); 143 } 144 return super.createCollection(key); 145 } 146 147 /** 148 * Returns the comparator that orders the multimap keys. 149 */ 150 public Comparator<? super K> keyComparator() { 151 return keyComparator; 152 } 153 154 @Override 155 public Comparator<? super V> valueComparator() { 156 return valueComparator; 157 } 158 159 /* 160 * The following @GwtIncompatible methods override the methods in 161 * AbstractSortedKeySortedSetMultimap, so GWT will fall back to the ASKSSM implementations, 162 * which return SortedSets and SortedMaps. 163 */ 164 } 165